﻿package bdz.projects.lavender.cms.model
{
	import flash.events.EventDispatcher;
	import flash.utils.Dictionary;
	
	/**
	 * ...
	 * @author ...
	 */
	public class ObjectBase extends EventDispatcher
	{
		protected var _attributes:Dictionary;
		protected var raw:XML;
		protected var _objects:Array;
		protected var _containers:Array;
		protected var _properties:Array;
		public var children:Array;
		public var _showcomplexChildren:Boolean = false;
		
		public var read:Boolean;
		public var write:Boolean;
		
		public var deny:Boolean;
		
		public function ObjectBase(xm:XML) {
			_attributes = new Dictionary();
			_objects = new Array();
			raw = xm;
			parse();
			read = Boolean(Number(xm.@read));
			write = Boolean(Number(xm.@write));
		}
		protected function parse():void {
			if(raw){
				var objs:XMLList = raw.object;
				var conts:XMLList = raw.container
				
				for each(var odata:XML in objs) {
					if(odata.@read == "1"){
						var opush:ObjectData = new ObjectData(odata);
						 opush.parentHasWrite = Boolean(Number(raw.@write));
						_objects.push(opush);
					}
				}
				if (conts.length()) {
					_containers = new Array();
				}
				for each(var cdata:XML in conts) {
					if(cdata.@read == "1"){
						var cpush:ContainerData = new ContainerData(cdata);
						cpush.parentHasWrite = Boolean(Number(raw.@write)); 
						_containers.push(cpush);
					}
				}
				var props:XMLList = raw.property;
				if(props.length()){
					_properties = new Array();
					for each (var prop:XML in props){
						if(prop.@hidden == "0"){
							var ppush:PropertyData = new PropertyData(prop);
							ppush.parentHasWrite = Boolean(Number(raw.@write)); 
							_properties.push(ppush);
						}
					}
				}
				applyAttributes();
				children = _containers;
			}
		}
		
		protected function applyAttributes():void {
			var attlist:XMLList = raw.@ * ;
			for each(var atts:* in attlist) {
				_attributes[atts.name().toString()] = atts.toString();
			}
		}
		
		public function toXML():XML {
			
			var ret:XML = new XML("<"+raw.name()+"/>");
			
			for(var att:String in _attributes){
				ret["@"+att] = _attributes[att];
			}
			var counter:Number = 0;
			
			if (_objects && _objects.length) {
				ret.object = new XMLList();
			}
			if (_containers && _containers.length) {
				ret.container = new XMLList();
			}
			if (_properties && _properties.length) {
				ret.property = new XMLList();
			}
			counter = 0;
			for each(var _obj:ObjectData in _objects) {
				ret.object[counter] = _obj.toXML();
				counter++;
			}
			for each(var conts:ContainerData in _containers) {
				ret.container[counter] = conts.toXML();
				counter++;
			}
			counter = 0;
			for each(var _prop:PropertyData in _properties) {
				ret.property[counter] = _prop.toXML();
				counter++;
			}
			return ret;
		}
		public function getProperty(nme:String):String{
			for each(var prop:PropertyData in _properties){
				if(prop.getAttribute("name") == nme){
					return prop.value;
				}
			}
			return null;
		}
		public function queryPropertyAttribute(nme:String, val:String):String{
			for each(var prop:PropertyData in _properties){
				if(prop.getAttribute(nme) == val){
					return prop.value;
				}
			}
			return null;
		}
		
		public function addObjectAt(xm:XML, index:Number):void {
			_objects.splice(index, 0, new ObjectData(xm));
		}
		public function addObject(xm:XML):void {
			addObjectAt(xm, _objects.length);
		}
		public function replaceObjectAt(indx:Number, val:ObjectData):void{
			_objects[indx] = val;
		}
		public function deleteObjectWidthID(id:String):void{
			for (var i:Number = 0;i<_objects.length;i++){
				if(_objects[i].oid == id){
					_objects.splice(i, 1);
					break;
				}
			}
		}
		public function deleteContainerWidthID(id:String):void{
			for (var i:Number = 0;i<_containers.length;i++){
				if(containers[i].oid == id){
					containers.splice(i, 1);
					break;
				}
			}
		}
		public function deleteObject(index:Number):void {
			_objects.splice(index, 1);
		}
		public function addContainerAt(xm:XML, index:Number):void {
			_containers.splice(index, 0, new ContainerData(xm));
		}
		public function addContainer(xm:XML):void {
			addContainerAt(xm, _containers.length);
		}
		public function deleteContainer(index:Number):void {
			_containers.splice(index, 1);
		}
		public function get containers():Array {
			_containers.sortOn("order", Array.NUMERIC);
			return _containers;
		}
		public function get objects():Array {
			_objects.sortOn("order", Array.NUMERIC);
			return _objects;
		}
		public function editAttribute(pname:String, val:String):void{
			_attributes[pname] = val;
		}
		public function getAttribute(pname:String):*{
			if(_attributes[pname] == "" || _attributes[pname] == "None"){
				return null;
			} 
			return _attributes[pname];
		}
		public function get attributes():Dictionary {
			return _attributes ;
		}
		public function get name():String {
			return raw.@name;
		}
		public function set showComplexChildren(comp:Boolean):void {
			_showcomplexChildren = comp;
		}
		public function get hasComplexChildren():Boolean {
			return getAttribute("type") == "complex";
		}
		public function set oid(id:String):void{
			_attributes["id"] = oid;
			raw.@id = oid;
		}
		public function get oid():String{
			return getAttribute("id");
		}
		public function get order():Number{
			
			return Number(getAttribute("order"));
		}
		public function set order(o:Number):void{
			_attributes["order"] = o.toString();
		}
		public function get permissions():String{
			return "";
		}
		
	}
	
}